﻿package com.study.controller;

import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
    1、设置字符集编码格式     
    2、设置根路径base
    3、封装转发或重定向
         f代表转发
         r代表重定向
    4、统一的异常处理（跳转到error页面）
  5、使其子类能够调用自身的[独有]方法	
 * @author SMILE 
 * @version 创建时间：2019年4月29日  下午1:40:11
 */
public abstract class BaseServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	public HttpSession session;
	/**抽象方法，
	 * 要求子类必须重写该方法。
	 * 没有参数时，默认的处理方法。一般是Servlet第一次请求的处理方法
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	public abstract String excute(HttpServletRequest request, 
			   HttpServletResponse response) throws Exception;
	

	@Override
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
			System.out.println("base...................");
			//1、设置字符集编码格式    
			request.setCharacterEncoding("utf-8");
			response.setCharacterEncoding("utf-8");
			response.setContentType("text/html;charset=utf-8");
			
			session = request.getSession();
			PrintWriter out = response.getWriter();
			try {
				//2、设置根路径base
				session.setAttribute("_ctx", request.getContextPath()+"/");
				//3、封装转发或重定向
				// 转发---get请求Servlet，然后转发跳到对应的jsp页面，地址栏不会发生变化
				// forward("list",request,response);
				// 重定向——请求的是Servlet地址
				// redirect("reg",response);
				
				//从请求参数中获取v（请求的方法）
				String v = request.getParameter("v");
				System.out.println("v:"+v);
				//配置默认方法
				String method = "excute";
				if(v!=null && !"".equals(v)) {
					method=v;
				}
				
				// 从当前Class对象中，获取对应的方法对象
				Method m = this.getClass().getDeclaredMethod(method, HttpServletRequest.class,HttpServletResponse.class);
				Object result = m.invoke(this, request,response);
				System.out.println(method+"方法的返回值是："+result);
				//判断方法是否有返回类型
				if(result!=null) {
					if(result.toString().startsWith("f:")) {
						//转发
						forward(result.toString().substring(2), request, response);
					}else if(result.toString().startsWith("r:")) {
						//重定向
						redirect(result.toString().substring(2), response);
					}else {
						//直接输出结果
						out.print(result.toString());
						out.flush();
						out.close();
					}
				}
			
			} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
				e.printStackTrace();
				session.setAttribute("_err", "服务器发生错误-"+e.getMessage());
				try {
					forward("error", request, response);
				} catch (ServletException | IOException e1) {
					e1.printStackTrace();
				}
			}finally {
				out.close();
			}
			
			

		
	}
	
	/**转发
	 * @param jspName
	 * @param request
	 * @param response
	 * @throws ServletException
	 * @throws IOException
	 */
	public void forward(String jspName,
						HttpServletRequest request,
						HttpServletResponse response) throws ServletException, IOException {
		request.getRequestDispatcher("WEB-INF/jsp/"+jspName+".jsp").forward(request, response);
	}
	
	/**重定向
	 * @param serName
	 * @param response
	 * @throws IOException
	 */
	public void redirect(String serName,HttpServletResponse response) throws IOException{
		response.sendRedirect(serName);
	}

}